﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Web.UI.WebControls;
using NetDon.OA.Data;
using NetDon.OA.Data.CollectionClasses;
using NetDon.OA.Data.DaoClasses;
using NetDon.OA.Data.EntityClasses;
using NetDon.OA.Data.HelperClasses;
using NetDon.OA.Data.Linq;
using NetDon.OA.Data.RelationClasses;
using NetDon.OA.Interface;
using NetDon.OA.Interface.eLogistics;
using SD.LLBLGen.Pro.ORMSupportClasses;

namespace NetDon.OA.Business
{
    public partial class RevenueMachineAccountService : IRevenueMachineAccountService
    {
        public int GetRevenueMachineAccountInvoicesCount(RevenueMachineAccountInvoiceSearchCriteria criteria)
        {
            var collection = new RevenueMachineAccountInvoiceCollection();
            return collection.GetDbCount(GetRevenueMachineAccountInvoicePredicate(criteria), GetRevenueMachineAccountInvoiceSearchRelations());
        }

        private IRelationCollection GetRevenueMachineAccountInvoiceSearchRelations()
        {
            var relation = new RelationCollection();

            relation.Add(new DynamicRelation(EntityType.RevenueMachineAccountInvoiceEntity, JoinHint.Left,
                                             EntityType.CompanyEntity, string.Empty, string.Empty,
                                             CompanyFields.CompanyId == RevenueMachineAccountInvoiceFields.AreaId));
            relation.Add(new DynamicRelation(EntityType.RevenueMachineAccountInvoiceEntity, JoinHint.Left,
                                            EntityType.CustomerInfoEntity, string.Empty, string.Empty,
                                            CustomerInfoFields.CustomerId == RevenueMachineAccountInvoiceFields.CustomerId));
            relation.Add(new DynamicRelation(EntityType.RevenueMachineAccountInvoiceEntity, JoinHint.Left, EntityType.UserEntity, string.Empty, string.Empty,
                                             RevenueMachineAccountInvoiceFields.LastUpdatedBy == UserFields.UserId));
            return relation;
        }

        private IRelationCollection GetRevenueMachineAccountInvoiceOrderSearchRelations()
        {
            var relation = new RelationCollection(RevenueMachineAccountInvoiceOrderEntity.Relations.RevenueMachineAccountEntityUsingRevenueMachineAccountId, JoinHint.Left);
            relation.Add(RevenueMachineAccountEntity.Relations.IssuingOrderEntityUsingIssuingOrderId);

            return relation;
        }

        private IRelationCollection GetRevenueMachineAccountForInvoicesSearchRelations()
        {
            var relation = new RelationCollection(RevenueMachineAccountEntity.Relations.IssuingOrderEntityUsingIssuingOrderId);

            return relation;
        }

        public DataTable SearchRevenueMachineAccountInvoiceByCondition(RevenueMachineAccountInvoiceSearchCriteria criteria, string sortExpression, SortDirection sortDirection, int pageSize, int pageIndex)
        {
            var fields = new EntityFields(23);
            var index = 0;

            fields[index++] = RevenueMachineAccountInvoiceFields.Id;
            fields[index++] = RevenueMachineAccountInvoiceFields.RouteTypeId;
            fields[index++] = CustomerInfoFields.CustomerName;
            fields[index++] = RevenueMachineAccountInvoiceFields.ExpenseDescription;
            fields[index++] = RevenueMachineAccountInvoiceFields.ConfirmInvoiceDate;
            fields[index++] = RevenueMachineAccountInvoiceFields.InvoiceNo;
            fields[index++] = RevenueMachineAccountInvoiceFields.InvoiceType;
            fields[index++] = RevenueMachineAccountInvoiceFields.AccountsReceivableDate;
            fields[index++] = RevenueMachineAccountInvoiceFields.InvoiceCurrencyType;
            fields[index++] = RevenueMachineAccountInvoiceFields.StateofAccountAmount;
            fields[index++] = RevenueMachineAccountInvoiceFields.InvoiceAmount;
            fields[index++] = RevenueMachineAccountInvoiceFields.InvoiceDescription;

            fields[index++] = RevenueMachineAccountInvoiceFields.LastUpdatedBy;
            fields[index++] = RevenueMachineAccountInvoiceFields.LastUpdatedDate;

            fields[index++] = UserFields.UserName;
            fields[index++] = RevenueMachineAccountInvoiceFields.ConfirmAccountsReceivableDate;

            fields[index++] = RevenueMachineAccountInvoiceFields.TotalAccountReceiptAmount;
            fields[index++] = new EntityField("UnReceivedAmount", RevenueMachineAccountInvoiceFields.TotalAccountReceiptAmount - RevenueMachineAccountInvoiceFields.InvoiceAmount);
            fields[index++] = RevenueMachineAccountInvoiceFields.AccountReceiptExceptions;
            fields[index++] = RevenueMachineAccountInvoiceFields.AccountReceiptComments;
            fields[index++] = new EntityField("InvoiceCurrencyTypeText", new DbFunctionCall("dbo.GeDataDictionary({0})", new object[] { RevenueMachineAccountInvoiceFields.InvoiceCurrencyType }));
            fields[index++] = RevenueMachineAccountInvoiceFields.IsAccountReceiptCompleted;
            fields[index++] = CompanyFields.CompanyName;

            IEntityField sortField = null;
            switch (sortExpression)
            {
                case "Id":
                    sortField = RevenueMachineAccountInvoiceFields.Id;
                    break;
                case "RouteTypeId":
                    sortField = RevenueMachineAccountInvoiceFields.RouteTypeId;
                    break;
                case "CustomerName":
                    sortField = CustomerInfoFields.CustomerName;
                    break;
                case "ExpenseDescription":
                    sortField = RevenueMachineAccountInvoiceFields.ExpenseDescription;
                    break;
                case "ConfirmInvoiceDate":
                    sortField = RevenueMachineAccountInvoiceFields.ConfirmInvoiceDate;
                    break;
                case "InvoiceNo":
                    sortField = RevenueMachineAccountInvoiceFields.InvoiceNo;
                    break;
                case "InvoiceType":
                    sortField = RevenueMachineAccountInvoiceFields.InvoiceType;
                    break;
                case "AccountsReceivableDate":
                    sortField = RevenueMachineAccountInvoiceFields.AccountsReceivableDate;
                    break;
                case "InvoiceCurrencyType":
                    sortField = RevenueMachineAccountInvoiceFields.InvoiceCurrencyType;
                    break;

                case "StateofAccountAmount":
                    sortField = RevenueMachineAccountInvoiceFields.StateofAccountAmount;
                    break;
                case "InvoiceAmount":
                    sortField = RevenueMachineAccountInvoiceFields.InvoiceAmount;
                    break;
                case "InvoiceDescription":
                    sortField = RevenueMachineAccountInvoiceFields.InvoiceDescription;
                    break;


                case "UserName":
                    sortField = UserFields.UserName;
                    break;
                case "LastUpdatedDate":
                    sortField = RevenueMachineAccountInvoiceFields.LastUpdatedDate;
                    break;
                case "TotalAccountReceiptAmount":
                    sortField = RevenueMachineAccountInvoiceFields.TotalAccountReceiptAmount;
                    break;
                case "UnReceivedAmount":
                    sortField = fields[16];
                    break;
                case "AccountReceiptExceptions":
                    sortField = RevenueMachineAccountInvoiceFields.AccountReceiptExceptions;
                    break;
                case "AccountReceiptComments":
                    sortField = RevenueMachineAccountInvoiceFields.AccountReceiptComments;
                    break;
                    ;

            }
            SortExpression expression;
            if (sortField != null)
            {
                SortOperator sortOperator = sortDirection == SortDirection.Ascending
                                                ? SortOperator.Ascending
                                                : SortOperator.Descending;
                expression = new SortExpression((EntityField)sortField | sortOperator);
            }
            else
            {
                expression = new SortExpression(RevenueMachineAccountInvoiceFields.ConfirmInvoiceDate | SortOperator.Descending);
                expression.Add(RevenueMachineAccountInvoiceFields.InvoiceNo | SortOperator.Ascending);

            }


            var table = new DataTable();
            var dao = new TypedListDAO();
            dao.GetMultiAsDataTable(fields, table, 0, expression, GetRevenueMachineAccountInvoicePredicate(criteria),
                                    GetRevenueMachineAccountInvoiceSearchRelations(), false, null, null, pageIndex + 1, pageSize);


            return table;
        }
        public bool RemoveRevenueMachineAccountInvoices(Guid id)
        {
            var trans = new Transaction(IsolationLevel.ReadCommitted, "RemoveRevenueMachineAccountInvoices");
            try
            {
                var collection = new RevenueMachineAccountInvoiceOrderCollection();
                collection.GetMulti(RevenueMachineAccountInvoiceOrderFields.RevenueMachineAccountInvoiceId == id);
                foreach (var entity in collection)
                {
                    var revenueMachineAccouint = entity.RevenueMachineAccount;
                    revenueMachineAccouint.IsInvoiced = false;
                    revenueMachineAccouint.IsAccountsReceivable = false;
                    revenueMachineAccouint.ConfirmAccountsReceiptDate = null;
                    revenueMachineAccouint.ConfirmInvoiceDate = null;
                    trans.Add(revenueMachineAccouint);
                    revenueMachineAccouint.Save();
                    trans.Add(entity);
                    entity.Delete();
                }
                //delete all the receipts
                var collection1 = new RevenueMachineAccountInvoiceReceiptCollection();
                collection1.GetMulti(RevenueMachineAccountInvoiceReceiptFields.RevenueMachineAccountInvoiceId == id);
                foreach (var entity in collection1)
                {
                    trans.Add(entity);
                    entity.Delete();
                }

                var machineAccountEntity = new RevenueMachineAccountInvoiceEntity(id);
                trans.Add(machineAccountEntity);
                machineAccountEntity.Delete();

                trans.Commit();
                return true;
            }
            catch (Exception)
            {
                trans.Rollback();
                throw;
            }
        }

        public RevenueMachineAccountInvoiceData GetRevenueMachineAccountInvoice(Guid revenueMachineAccountId)
        {
            var meta = new LinqMetaData();
            var data = (from revenueMachineAccount in meta.RevenueMachineAccountInvoice
                        where revenueMachineAccount.Id == revenueMachineAccountId
                        select revenueMachineAccount).FirstOrDefault();
            if (data == null) return null;
            return GetRevenueMachineAccountInvoiceData(data);

        }

        public bool IsRevenueMachineAccountInvoiceExists(Guid issuingOrderId)
        {
            var meta = new LinqMetaData();
            var revenueMachineAccounts = new RevenueMachineAccountCollection();
            revenueMachineAccounts.GetMulti(RevenueMachineAccountFields.IssuingOrderId == issuingOrderId);
            var renvenueMachineAccount = revenueMachineAccounts.FirstOrDefault();
            if (renvenueMachineAccount != null)
            {
                return
                    meta.RevenueMachineAccountInvoiceOrder.Any(
                        invoice => invoice.RevenueMachineAccountId == renvenueMachineAccount.Id);
            }
            return false;



        }

        public DataTable GetRevenueMachineAccountInvoiceOrders(Guid revenueMachineAccountInvoiceId)
        {

            var fields = new EntityFields(12);
            var index = 0;

            //0
            fields[index++] = new EntityField("Revenues", new ScalarQueryExpression(new EntityField("TotalDeliveryRevenue",
                                              new Expression(
                                                   IssuingOrderDeliveryFields.ConvertedOrderVolumnWeight,
                                                  ExOp.Mul, IssuingOrderDeliveryFields.RevenueUnitCost), AggregateFunction.Sum),
                                                                  IssuingOrderFields.Id ==
                                                                  IssuingOrderDeliveryFields.IssuingOrderId & IssuingOrderFields.Id == RevenueMachineAccountFields.IssuingOrderId, new RelationCollection(IssuingOrderEntity.Relations.IssuingOrderDeliveryEntityUsingIssuingOrderId)));


            //1
            fields[index++] = new EntityField("UnloadingCostWithFactory", new ScalarQueryExpression(new EntityField("TotalUnloadingCostWithFactory",
                                     new Expression(
                                          IssuingOrderDeliveryFields.ConvertedOrderVolumnWeight,
                                         ExOp.Mul, IssuingOrderDeliveryFields.GoodsUnloadingPriceRatio), AggregateFunction.Sum),
                                                         IssuingOrderFields.Id ==
                                                         IssuingOrderDeliveryFields.IssuingOrderId, new RelationCollection(IssuingOrderEntity.Relations.IssuingOrderDeliveryEntityUsingIssuingOrderId)));

            //2
            fields[index++] = new EntityField("TotalRevenues", new Expression(
          fields[0],
           ExOp.Add, RevenueMachineAccountFields.Subsidy) + new Expression(new Expression(
         fields[1],
           ExOp.Add, RevenueMachineAccountFields.CarSharingCostWithFactory), ExOp.Add, RevenueMachineAccountFields.OtherRevenue));



            //3
            fields[index++] = new EntityField("ActualOrderVolumn",
            new ScalarQueryExpression(IssuingOrderDeliveryFields.ActualEntruckingOrderVolumn.SetAggregateFunction(AggregateFunction.Sum), IssuingOrderFields.Id == IssuingOrderDeliveryFields.IssuingOrderId));
            //4
            fields[index++] = new EntityField("ActualOrderWeight",
         new ScalarQueryExpression(IssuingOrderDeliveryFields.ActualEntruckingOrderWeight.SetAggregateFunction(AggregateFunction.Sum), IssuingOrderFields.Id == IssuingOrderDeliveryFields.IssuingOrderId));
            //5
            fields[index++] = new EntityField("ActualOrderQuantity",
         new ScalarQueryExpression(IssuingOrderDeliveryFields.ActualEntruckingOrderQuantity.SetAggregateFunction(AggregateFunction.Sum), IssuingOrderFields.Id == IssuingOrderDeliveryFields.IssuingOrderId));


            fields[index++] = RevenueMachineAccountInvoiceOrderFields.Id;
            fields[index++] = RevenueMachineAccountFields.TransportationPlanCode;
            fields[index++] = RevenueMachineAccountFields.OrderCode;
            fields[index++] = IssuingOrderFields.ActualShippingDate;

            fields[index++] = IssuingOrderFields.ReceivingOrderDate;
            fields[index++] = RevenueMachineAccountFields.IssuingOrderId;

            IEntityField sort = null;

            SortExpression expression = new SortExpression
                               {
                                   RevenueMachineAccountFields.OrderCode | SortOperator.Ascending
                               };


            var table = new DataTable("RevenueMachineAccountDS");
            var dao = new TypedListDAO();
            dao.GetMultiAsDataTable(fields, table, 0, expression, RevenueMachineAccountInvoiceOrderFields.RevenueMachineAccountInvoiceId == revenueMachineAccountInvoiceId,
                                    GetRevenueMachineAccountInvoiceOrderSearchRelations(), false, null, null, 1, 100000);


            return table;
        }

        public DataTable GetRevenueMachineAccountForInvoices(RevenueMachineAccountForInvoiceSearchCriteria criteria)
        {

            var fields = new EntityFields(14);
            var index = 0;

            //0
            fields[index++] = new EntityField("Revenues", new ScalarQueryExpression(new EntityField("TotalDeliveryRevenue",
                                              new Expression(
                                                   IssuingOrderDeliveryFields.ConvertedOrderVolumnWeight,
                                                  ExOp.Mul, IssuingOrderDeliveryFields.RevenueUnitCost), AggregateFunction.Sum),
                                                                  IssuingOrderFields.Id ==
                                                                  IssuingOrderDeliveryFields.IssuingOrderId & IssuingOrderFields.Id == RevenueMachineAccountFields.IssuingOrderId, new RelationCollection(IssuingOrderEntity.Relations.IssuingOrderDeliveryEntityUsingIssuingOrderId)));
            //0


            //1
            fields[index++] = new EntityField("UnloadingCostWithFactory", new ScalarQueryExpression(new EntityField("TotalUnloadingCostWithFactory",
                                     new Expression(
                                        IssuingOrderDeliveryFields.ConvertedOrderVolumnWeight,
                                         ExOp.Mul, IssuingOrderDeliveryFields.GoodsUnloadingPriceRatio), AggregateFunction.Sum),
                                                         IssuingOrderFields.Id ==
                                                         IssuingOrderDeliveryFields.IssuingOrderId & IssuingOrderFields.Id == RevenueMachineAccountFields.IssuingOrderId, new RelationCollection(IssuingOrderEntity.Relations.IssuingOrderDeliveryEntityUsingIssuingOrderId)));

            //2
            fields[index++] = new EntityField("TotalRevenues", new Expression(new Expression(
           new Expression(new Expression(
         fields[1],
           ExOp.Add, RevenueMachineAccountFields.CarSharingCostWithFactory), ExOp.Add, RevenueMachineAccountFields.OtherRevenue), ExOp.Add, fields[0]), ExOp.Add, RevenueMachineAccountFields.Subsidy));



            //3
            fields[index++] = new EntityField("ActualOrderVolumn",
            new ScalarQueryExpression(IssuingOrderDeliveryFields.ActualEntruckingOrderVolumn.SetAggregateFunction(AggregateFunction.Sum), IssuingOrderFields.Id == IssuingOrderDeliveryFields.IssuingOrderId));
            //4
            fields[index++] = new EntityField("ActualOrderWeight",
         new ScalarQueryExpression(IssuingOrderDeliveryFields.ActualEntruckingOrderWeight.SetAggregateFunction(AggregateFunction.Sum), IssuingOrderFields.Id == IssuingOrderDeliveryFields.IssuingOrderId));
            //5
            fields[index++] = new EntityField("ActualOrderQuantity",
         new ScalarQueryExpression(IssuingOrderDeliveryFields.ActualEntruckingOrderQuantity.SetAggregateFunction(AggregateFunction.Sum), IssuingOrderFields.Id == IssuingOrderDeliveryFields.IssuingOrderId));
            //6
            fields[index++] = new EntityField("ExtraCost", new Expression(
                                                      new ScalarQueryExpression(
                                                          MachineAccountPaymentFields.OtherAmountFromManufactor.
                                                              SetAggregateFunction(AggregateFunction.Sum),
                                                          IssuingOrderFields.Id ==
                                                          MachineAccountPaymentFields.IssuingOrderId),
                                                      ExOp.Sub, new ScalarQueryExpression(
                                                                    MachineAccountPaymentFields.
                                                                        DeductionExceptionsAmount.SetAggregateFunction(
                                                                            AggregateFunction.Sum),
                                                                    IssuingOrderFields.Id ==
                                                                    MachineAccountPaymentFields.IssuingOrderId)));

            //7
            fields[index++] = new EntityField("StateofAccountAmount", new Expression(fields[2], ExOp.Sub, fields[6]));


            fields[index++] = RevenueMachineAccountFields.Id;
            fields[index++] = RevenueMachineAccountFields.TransportationPlanCode;
            fields[index++] = RevenueMachineAccountFields.OrderCode;
            fields[index++] = IssuingOrderFields.ActualShippingDate;

            fields[index++] = IssuingOrderFields.ReceivingOrderDate;
            fields[index++] = RevenueMachineAccountFields.IssuingOrderId;

            IEntityField sort = null;

            SortExpression expression = new SortExpression
                               {
                                   RevenueMachineAccountFields.OrderCode | SortOperator.Ascending
                               };


            var table = new DataTable("RevenueMachineAccountDS");
            var dao = new TypedListDAO();
            dao.GetMultiAsDataTable(fields, table, 0, expression, GetRevenueMachineAccountInvoiceOrderPredicate(criteria),
                                    GetRevenueMachineAccountForInvoicesSearchRelations(), false, null, null, 1, 100000);


            return table;
        }


        public bool ModifyRevenueMachineAccountInvoice(RevenueMachineAccountInvoiceData data)
        {
            var trans = new Transaction(IsolationLevel.ReadCommitted, "ModifyRevenueMachineAccountInvoice");
            try
            {
                var machineAccountEntity = new RevenueMachineAccountInvoiceEntity(data.Id);
                GetRevenueMachineAccountInvoiceEntity(machineAccountEntity, data);
                trans.Add(machineAccountEntity);
                machineAccountEntity.Save();
                AddRevenueMachineAccountInvoiceReceipt(data, trans, machineAccountEntity);
                //modify all the revenueMachineAccounts
                if (data.TotalAccountReceiptAmount == data.InvoiceAmount)
                {
                    UpdateRevenueMachineAccountsAccountReceived(machineAccountEntity, trans);
                }

                trans.Commit();
                return true;
            }
            catch (Exception)
            {
                trans.Rollback();
                throw;
            }

        }


        public bool ConfirmRevenueMachineAccountInvoice(Guid revenueMachineAccountInvoiceId)
        {
            var trans = new Transaction(IsolationLevel.ReadCommitted, "ConfirmRevenueMachineAccountInvoice");
            try
            {
                var machineAccountEntity = new RevenueMachineAccountInvoiceEntity(revenueMachineAccountInvoiceId);
                machineAccountEntity.IsAccountReceiptCompleted = true;
                machineAccountEntity.ConfirmAccountsReceivableDate = DateTime.Now;
                trans.Add(machineAccountEntity);
                machineAccountEntity.Save();
                //modify all the revenueMachineAccounts
                UpdateRevenueMachineAccountsAccountReceived(machineAccountEntity, trans);
                trans.Commit();
                return true;
            }
            catch (Exception)
            {
                trans.Rollback();
                throw;
            }

        }

        public bool AddRevenueMachineAccountInvoice(RevenueMachineAccountInvoiceData data)
        {
            var trans = new Transaction(IsolationLevel.ReadCommitted, "AddRevenueMachineAccountInvoice");
            try
            {
                var machineAccountEntity = new RevenueMachineAccountInvoiceEntity();
                GetRevenueMachineAccountInvoiceEntity(machineAccountEntity, data);
                machineAccountEntity.Id = data.Id;
                trans.Add(machineAccountEntity);
                machineAccountEntity.Save();
                //insert revenuemachineacount invoice orders
                foreach (var revenueMachineAccountInvoiceOrder in data.RevenueMachineAccountInvoiceOrders)
                {
                    var revenueMachineAccountInvoiceOrderEntity = new RevenueMachineAccountInvoiceOrderEntity();
                    revenueMachineAccountInvoiceOrderEntity = GetRevenueMachineAccountInvoiceOrderEntity(revenueMachineAccountInvoiceOrderEntity, revenueMachineAccountInvoiceOrder);

                    revenueMachineAccountInvoiceOrderEntity.RevenueMachineAccountId = revenueMachineAccountInvoiceOrder.RevenueMachineAccountId;
                    revenueMachineAccountInvoiceOrderEntity.RevenueMachineAccountInvoiceId = machineAccountEntity.Id;

                    trans.Add(revenueMachineAccountInvoiceOrderEntity);
                    revenueMachineAccountInvoiceOrderEntity.Save();
                    //update status
                    var revenueMachineAccountEntity = new RevenueMachineAccountEntity(revenueMachineAccountInvoiceOrder.RevenueMachineAccountId.Value);
                    revenueMachineAccountEntity.IsInvoiced = true;
                    revenueMachineAccountEntity.ConfirmInvoiceDate = data.ConfirmInvoiceDate;
                    trans.Add(revenueMachineAccountEntity);
                    revenueMachineAccountEntity.Save();
                }


                trans.Commit();
                return true;
            }
            catch (Exception)
            {
                trans.Rollback();
                throw;
            }
        }

        #region private methods

        private void UpdateRevenueMachineAccountsAccountReceived(RevenueMachineAccountInvoiceEntity revenueMachineAccountInvoiceEntity, Transaction trans)
        {
            var collection = new RevenueMachineAccountInvoiceOrderCollection();
            collection.GetMulti(RevenueMachineAccountInvoiceOrderFields.RevenueMachineAccountInvoiceId == revenueMachineAccountInvoiceEntity.Id);
            foreach (var entity in collection)
            {
                var revenueMachineAccouint = entity.RevenueMachineAccount;
                revenueMachineAccouint.IsAccountsReceivable = true;
                revenueMachineAccouint.ConfirmAccountsReceiptDate = DateTime.Now;
                trans.Add(revenueMachineAccouint);
                revenueMachineAccouint.Save();
                trans.Add(entity);
                entity.Delete();
            }

        }
        private IPredicate GetRevenueMachineAccountInvoiceOrderPredicate(RevenueMachineAccountForInvoiceSearchCriteria criteria)
        {
            var expression = new PredicateExpression();

            if (criteria.AreaId.HasValue && criteria.AreaId.Value != Guid.Empty)
            {
                expression.Add(RevenueMachineAccountFields.AreaId == criteria.AreaId);
            }

            if (criteria.IsStatementofAccountCompleted.HasValue)
            {
                expression.Add(RevenueMachineAccountFields.IsStatementofAccountCompleted == criteria.IsStatementofAccountCompleted);

            }
            if (criteria.IsInvoiced.HasValue)
            {
                expression.Add(RevenueMachineAccountFields.IsInvoiced == criteria.IsInvoiced);
            }
            if (criteria.ConfirmStatementofAccountDate != null)
            {
                if (criteria.ConfirmStatementofAccountDate.Start.HasValue)
                {
                    expression.Add(RevenueMachineAccountFields.ConfirmStatementofAccountDate >= criteria.ConfirmStatementofAccountDate.Start);
                }
                if (criteria.ConfirmStatementofAccountDate.End.HasValue)
                {
                    expression.Add(RevenueMachineAccountFields.ConfirmStatementofAccountDate <= criteria.ConfirmStatementofAccountDate.End);
                }
            }
            if (criteria.DueInvoiceDate != null)
            {
                if (criteria.DueInvoiceDate.Start.HasValue)
                {
                    expression.Add(RevenueMachineAccountFields.DueInvoiceDate >= criteria.DueInvoiceDate.Start);
                }
                if (criteria.DueInvoiceDate.End.HasValue)
                {
                    expression.Add(RevenueMachineAccountFields.DueInvoiceDate <= criteria.DueInvoiceDate.End);
                }
            }


            if (criteria.CustomerId.HasValue && criteria.CustomerId.Value != Guid.Empty)
            {
                expression.Add(IssuingOrderFields.CustomerId == criteria.CustomerId);
            }
            if (criteria.RouteTypeId.HasValue && criteria.RouteTypeId.Value != Guid.Empty)
            {
                expression.Add(IssuingOrderFields.RouteTypeId == criteria.RouteTypeId);
            }

            return expression;
        }

        private IPredicate GetRevenueMachineAccountInvoicePredicate(RevenueMachineAccountInvoiceSearchCriteria criteria)
        {
            var expression = new PredicateExpression();

            if (criteria.AreaId.HasValue && criteria.AreaId.Value != Guid.Empty)
            {
                expression.Add(RevenueMachineAccountInvoiceFields.AreaId == criteria.AreaId);
            }

            if (!string.IsNullOrEmpty(criteria.InvoiceNO))
            {
                expression.Add(RevenueMachineAccountInvoiceFields.InvoiceNo % ("%" + criteria.InvoiceNO + "%"));
            }



            if (criteria.ConfirmInvoiceDate != null)
            {
                if (criteria.ConfirmInvoiceDate.Start.HasValue)
                {
                    expression.Add(RevenueMachineAccountInvoiceFields.ConfirmInvoiceDate >= criteria.ConfirmInvoiceDate.Start);
                }
                if (criteria.ConfirmInvoiceDate.End.HasValue)
                {
                    expression.Add(RevenueMachineAccountInvoiceFields.ConfirmInvoiceDate <= criteria.ConfirmInvoiceDate.End);
                }
            }

            if (criteria.AccountsReceivableDate != null)
            {
                if (criteria.AccountsReceivableDate.Start.HasValue)
                {
                    expression.Add(RevenueMachineAccountInvoiceFields.AccountsReceivableDate >= criteria.AccountsReceivableDate.Start);
                }
                if (criteria.AccountsReceivableDate.End.HasValue)
                {
                    expression.Add(RevenueMachineAccountInvoiceFields.AccountsReceivableDate <= criteria.AccountsReceivableDate.End);
                }
            }

            if (criteria.ConfirmAccountsReceivableDate != null)
            {
                if (criteria.ConfirmAccountsReceivableDate.Start.HasValue)
                {
                    expression.Add(RevenueMachineAccountInvoiceFields.ConfirmAccountsReceivableDate >= criteria.ConfirmAccountsReceivableDate.Start);
                }
                if (criteria.ConfirmAccountsReceivableDate.End.HasValue)
                {
                    expression.Add(RevenueMachineAccountInvoiceFields.ConfirmAccountsReceivableDate <= criteria.ConfirmAccountsReceivableDate.End);
                }
            }


            if (criteria.CustomerId.HasValue && criteria.CustomerId.Value != Guid.Empty)
            {
                expression.Add(RevenueMachineAccountInvoiceFields.CustomerId == criteria.CustomerId);
            }
            if (criteria.RouteTypeId.HasValue && criteria.RouteTypeId.Value != Guid.Empty)
            {
                expression.Add(RevenueMachineAccountInvoiceFields.RouteTypeId == criteria.RouteTypeId);
            }
   
                if (criteria.InvoiceAmountStart.HasValue)
                {
                    expression.Add(RevenueMachineAccountInvoiceFields.InvoiceAmount >= criteria.InvoiceAmountStart);
                }
                if (criteria.InvoiceAmountEnd.HasValue)
                {
                    expression.Add(RevenueMachineAccountInvoiceFields.InvoiceAmount <= criteria.InvoiceAmountEnd);
                }
         
            if (criteria.InvoiceType.HasValue && criteria.InvoiceType.Value != Guid.Empty)
            {
                expression.Add(RevenueMachineAccountInvoiceFields.InvoiceType == criteria.InvoiceType);
            }
            if (criteria.CurrencyType.HasValue && criteria.CurrencyType.Value != Guid.Empty)
            {
                expression.Add(RevenueMachineAccountInvoiceFields.InvoiceCurrencyType == criteria.CurrencyType);
            }
            return expression;
        }

        private RevenueMachineAccountInvoiceData GetRevenueMachineAccountInvoiceData(RevenueMachineAccountInvoiceEntity revenueMachineAccountEntity)
        {
            var revenueMachineAccountData = new RevenueMachineAccountInvoiceData()
            {
                Id = revenueMachineAccountEntity.Id,
                AreaId =
                    revenueMachineAccountEntity.AreaId,

                RouteTypeId = revenueMachineAccountEntity.RouteTypeId,

                CustomerId = revenueMachineAccountEntity.CustomerId,

                ExpenseDescription = revenueMachineAccountEntity.ExpenseDescription,

                InvoiceNO = revenueMachineAccountEntity.InvoiceNo,
                InvoiceType = revenueMachineAccountEntity.InvoiceType,
                InvoiceCurrencyType = revenueMachineAccountEntity.InvoiceCurrencyType,


                StateofAccountAmount = revenueMachineAccountEntity.StateofAccountAmount,
                InvoiceAmount = revenueMachineAccountEntity.InvoiceAmount,

                InvoiceDescription = revenueMachineAccountEntity.InvoiceDescription,
                AccountsReceivableDate = revenueMachineAccountEntity.AccountsReceivableDate,
                AccountReceiptExceptions = revenueMachineAccountEntity.AccountReceiptExceptions,
                IsAccountReceiptExceptions = revenueMachineAccountEntity.IsAccountReceiptExceptions,

                AccountReceiptComments = revenueMachineAccountEntity.AccountReceiptComments,
                TotalAccountReceiptAmount = revenueMachineAccountEntity.TotalAccountReceiptAmount,
                ConfirmInvoiceDate = revenueMachineAccountEntity.ConfirmInvoiceDate,

                CreateBy = revenueMachineAccountEntity.CreateBy,
                CreatedDate = revenueMachineAccountEntity.CreatedDate,
                LastUpdatedBy = revenueMachineAccountEntity.LastUpdatedBy,
                LastUpdatedDate = revenueMachineAccountEntity.LastUpdatedDate,
                UnReceivedAmount = revenueMachineAccountEntity.InvoiceAmount - revenueMachineAccountEntity.TotalAccountReceiptAmount,
                IsAccountReceiptCompleted = revenueMachineAccountEntity.IsAccountReceiptCompleted ?? false,
                ConfirmAccountsReceivableDate =revenueMachineAccountEntity.ConfirmAccountsReceivableDate
            };

            return revenueMachineAccountData;
        }
        private RevenueMachineAccountInvoiceEntity GetRevenueMachineAccountInvoiceEntity(RevenueMachineAccountInvoiceEntity revenueMachineAccountEntity, RevenueMachineAccountInvoiceData revenueMachineAccountData)
        {

            revenueMachineAccountEntity.Id = revenueMachineAccountData.Id;
            revenueMachineAccountEntity.AreaId =
                revenueMachineAccountData.AreaId;

            revenueMachineAccountEntity.RouteTypeId = revenueMachineAccountData.RouteTypeId;

            revenueMachineAccountEntity.CustomerId = revenueMachineAccountData.CustomerId;

            revenueMachineAccountEntity.ExpenseDescription = revenueMachineAccountData.ExpenseDescription;

            revenueMachineAccountEntity.InvoiceNo = revenueMachineAccountData.InvoiceNO;
            revenueMachineAccountEntity.InvoiceType = revenueMachineAccountData.InvoiceType;
            revenueMachineAccountEntity.InvoiceCurrencyType = revenueMachineAccountData.InvoiceCurrencyType;
            revenueMachineAccountEntity.StateofAccountAmount = revenueMachineAccountData.StateofAccountAmount;
            revenueMachineAccountEntity.InvoiceAmount = revenueMachineAccountData.InvoiceAmount;

            revenueMachineAccountEntity.InvoiceDescription = revenueMachineAccountData.InvoiceDescription;
            revenueMachineAccountEntity.AccountsReceivableDate = revenueMachineAccountData.AccountsReceivableDate;
            revenueMachineAccountEntity.AccountReceiptExceptions = revenueMachineAccountData.AccountReceiptExceptions;
            revenueMachineAccountEntity.IsAccountReceiptExceptions =
                revenueMachineAccountData.IsAccountReceiptExceptions ?? false;

            revenueMachineAccountEntity.AccountReceiptComments = revenueMachineAccountData.AccountReceiptComments;
            revenueMachineAccountEntity.TotalAccountReceiptAmount =
                revenueMachineAccountData.TotalAccountReceiptAmount;
            revenueMachineAccountEntity.ConfirmInvoiceDate = revenueMachineAccountData.ConfirmInvoiceDate;

            revenueMachineAccountEntity.CreateBy = revenueMachineAccountData.CreateBy.Value;
            revenueMachineAccountEntity.CreatedDate = revenueMachineAccountData.CreatedDate.Value;
            revenueMachineAccountEntity.LastUpdatedBy = revenueMachineAccountData.LastUpdatedBy.Value;
            revenueMachineAccountEntity.LastUpdatedDate = revenueMachineAccountData.LastUpdatedDate.Value;
            revenueMachineAccountEntity.IsAccountReceiptCompleted = revenueMachineAccountData.IsAccountReceiptCompleted;
            revenueMachineAccountEntity.ConfirmAccountsReceivableDate =
                revenueMachineAccountData.ConfirmAccountsReceivableDate;
            return revenueMachineAccountEntity;
        }


        private RevenueMachineAccountInvoiceOrderEntity GetRevenueMachineAccountInvoiceOrderEntity(RevenueMachineAccountInvoiceOrderEntity revenueMachineAccountEntity, RevenueMachineAccountInvoiceOrderData revenueMachineAccountData)
        {

            revenueMachineAccountEntity.Id = revenueMachineAccountData.Id;
            revenueMachineAccountEntity.AreaId =
                revenueMachineAccountData.AreaId;

            revenueMachineAccountEntity.RevenueMachineAccountId = revenueMachineAccountData.RevenueMachineAccountId;

            revenueMachineAccountEntity.RevenueMachineAccountInvoiceId = revenueMachineAccountData.RevenueMachineAccountInvoiceId;
            revenueMachineAccountEntity.OrderCode = revenueMachineAccountData.OrderCode;
            revenueMachineAccountEntity.CreateBy = revenueMachineAccountData.CreateBy.Value;
            revenueMachineAccountEntity.CreatedDate = revenueMachineAccountData.CreatedDate.Value;
            revenueMachineAccountEntity.LastUpdatedBy = revenueMachineAccountData.LastUpdatedBy.Value;
            revenueMachineAccountEntity.LastUpdatedDate = revenueMachineAccountData.LastUpdatedDate.Value;

            return revenueMachineAccountEntity;
        }

        #endregion
    }
}
